#include "clientsocket.h"
#include "serversocket.h"

ClientSocket::ClientSocket(QObject *parent) :
    QObject(parent)
{
    iUdpDiscoverySocket = 0;
    udpOnly = false;
}

bool ClientSocket::UdpOnly()
{
    return udpOnly;
}

void ClientSocket::setUdpOnly(bool udb)
{
    udpOnly = udb;
}


ClientSocket::~ClientSocket()
{
    stop();
}

void ClientSocket::start()
{
    // ** UDP **
    if (!iUdpDiscoverySocket) {
        iUdpDiscoverySocket = new QUdpSocket(this);
        iUdpDiscoverySocket->bind(SERVER_PORT, QUdpSocket::ShareAddress);
        QObject::connect(iUdpDiscoverySocket, SIGNAL(readyRead()),this, SLOT(udpGetData()));
    }
    writeLog("Started");
}

void ClientSocket::stop()
{
    if (!iUdpDiscoverySocket) {
        iUdpDiscoverySocket->close();
        //delete iUdpDiscoverySocket;
        iUdpDiscoverySocket = 0;
    }

    if (!iCommTcpSocket) {
        iCommTcpSocket->close();
        //delete iCommTcpSocket;
        iCommTcpSocket = 0;
    }

}

void ClientSocket::udpGetData()
{
    while (iUdpDiscoverySocket->hasPendingDatagrams()) {
        QByteArray datagram;
        datagram.resize(iUdpDiscoverySocket->pendingDatagramSize());
        iUdpDiscoverySocket->readDatagram(datagram.data(), datagram.size());

        QString data(datagram);

        if (!udpOnly && datagram.startsWith(SERVER_ID)) {
            writeLog("Discovered: "+data);
            QList<QByteArray> ls = datagram.split('@');
            QHostAddress address = QHostAddress( QString(ls[1]) );
            startTcpCommunication(address);
        }

        if (udpOnly && datagram.startsWith(SERVER_ID)) {
            writeLog("From UDP: "+data);
            sendToServer("UDP Hello from Client");
        }

        break;
    }
}

void ClientSocket::writeLog(QString log)
{
    log = log.prepend("[Client] ");
    qDebug() << log;
    emit clientLog(log);
}

void ClientSocket::startTcpCommunication(const QHostAddress& address)
{
    // ** TCP **
    if (!iCommTcpSocket) {
        iCommTcpSocket = new QTcpSocket(this);
        QObject::connect(iCommTcpSocket, SIGNAL(readyRead()), this, SLOT(readServerTcpData()));
        QObject::connect(iCommTcpSocket, SIGNAL(connected()), this, SLOT(connectedToServer()));
        iCommTcpSocket->connectToHost(address, SERVER_PORT);
        iServerAddress = address.toString();

        // Stop reading UDP
        iUdpDiscoverySocket->close();

        writeLog(QString("Connection to Server %1...").arg(address.toString()));
    }
}

void ClientSocket::connectedToServer()
{
    emit connected(iServerAddress);
    writeLog("Connected");
    sendToServer("Hello from Client");
}

void ClientSocket::readServerTcpData()
{
    QString msg(iCommTcpSocket->readAll());
    writeLog("From Server: "+msg);
}

void ClientSocket::sendToServer(QString msg)
{
    QByteArray datagram;
    if (udpOnly) {
        datagram.append(QString(CLIENT_ID));
        datagram.append(msg);
        iUdpDiscoverySocket->writeDatagram(datagram.data(), datagram.size(),
                                           QHostAddress::Broadcast, SERVER_PORT);
    } else {
        datagram.append(msg);
        iCommTcpSocket->write(datagram);
    }
    writeLog("To Server: "+msg);
}


